#include "util.h"

#include <iostream>

 #include <sys/time.h>
#include <sstream>

#include "log.h"
#include "fiber.h"


namespace sylar
{

sylar::Logger::LoggerPtr g_logger = SYLAR_LOG_NAME("system");

pid_t GetThreadId()
{
    return syscall(SYS_gettid);
}

uint32_t GetFiberId()
{
    return sylar::Fiber::GetFiberId();
}


// 堆栈，层，越过即层
void Backtrace(std::vector<std::string>& bt, int size, int skip)
{
    // 协程中栈的大小有限 使用堆的方式分配内存, *array指向的是地址不会分配内存
    void** array = (void**)malloc(sizeof(void*) * size);
    size_t nbacknum = ::backtrace(array, size);

    char** strings = backtrace_symbols(array, nbacknum);

    if (nullptr == strings)
    {
        SYLAR_LOG_ERROR(g_logger) << "bracktrace_symbols error"; 
        free(array);
        return;
    }

    for (size_t i = skip; i < nbacknum; i++)
    {
        bt.push_back(strings[i]);
    }

    free(strings);
    free(array);
}

std::string BacktraceToStrig(int size, int skip, const std::string& prefix)
{
    std::vector<std::string> bt;

    sylar::Backtrace(bt, size, skip);

    std::stringstream ss;

    for(auto& i : bt)
    {
        ss << prefix << i << std::endl;
    }
    
    return ss.str();
}

//时间 ms
uint64_t GetCurrentMs()
{
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    return tv.tv_sec * 1000ul + tv.tv_usec / 1000ul;
}

uint64_t GetCurrentUs()
{
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    return tv.tv_sec * 1000 * 1000ul + tv.tv_usec / 1000ul;
}


}